💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    전체 흐름 Part1 | ✅저자: 이유정(박사)

    소스보기

    • 실제 사용 가능한 REST API를 설계하고 구현하는 전 과정을 익힌다.
    • Django로 만든 웹앱을 RESTful API 서버로 전환하는 과정을 단계적으로 체험한다.
    • 보안(인증/권한), 구조(링크 기반), 자동화(ViewSet/Router)를 통해 실무 수준의 API 구조를 익힌다.
    # 디렉토리 생성
    mkdir drf_tutorial 
    cd drf_tutorial
    
    # 가상환경 설정
    python3 -m venv venv
    source venv/bin/activate
    
    # 패키지 설치
    pip install django
    pip install djangorestframework
    
    # 서드파티 설치 Browsable API용
    pip install markdown
    
    # 새 프로젝트 생성
    django-admin startproject tutorial .
    
    # 새 앱 생성
    python manage.py startapp snippets
    

    tutorial/settings.py

    INSTALLED_APPS = [
        ...
        'rest_framework',
        'snippets',
    ]
    

    pygments 외부 패키지

    pip install pygments
    

    snippets/models.py

    from django.db import models
    from pygments.lexers import get_all_lexers
    from pygments.styles import get_all_styles
    
    LEXERS = [item for item in get_all_lexers() if item[1]]
    LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
    STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])
    
    
    class Snippet(models.Model):
        created = models.DateTimeField(auto_now_add=True)
        title = models.CharField(max_length=100, blank=True, default='')
        code = models.TextField()
        linenos = models.BooleanField(default=False)
        language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
        style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
    
        class Meta:
            ordering = ['created']
    
    
    # 마이그레이션
    python manage.py makemigrations snippets
    python manage.py migrate
    

    snippets/serializers.py 기본형

    from rest_framework import serializers
    from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
    
    class SnippetSerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        title = serializers.CharField(required=False, allow_blank=True, max_length=100)
        code = serializers.CharField(style={'base_template': 'textarea.html'})
        linenos = serializers.BooleanField(required=False)
        language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
        style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')
    
        def create(self, validated_data):
            return Snippet.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            for field in ['title','code','linenos','language','style']:
                setattr(instance, field, validated_data.get(field, getattr(instance, field)))
            instance.save()
            return instance
    

    🔷 ModelSerializer 버전 snippets/serializers.py

    from rest_framework import serializers
    from snippets.models import Snippet
    
    
    class SnippetSerializer(serializers.ModelSerializer):
        class Meta:
            model = Snippet
            fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
    

    snippets/views.py

    from django.http import HttpResponse, JsonResponse
    from django.views.decorators.csrf import csrf_exempt
    from rest_framework.parsers import JSONParser
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    
    
    @csrf_exempt
    def snippet_list(request):
        if request.method == 'GET':
            snippets = Snippet.objects.all()
            serializer = SnippetSerializer(snippets, many=True)
            return JsonResponse(serializer.data, safe=False)
    
        elif request.method == 'POST':
            data = JSONParser().parse(request)
            serializer = SnippetSerializer(data=data)
            if serializer.is_valid():
                serializer.save()
                return JsonResponse(serializer.data, status=201)
            return JsonResponse(serializer.errors, status=400)
    
    
    @csrf_exempt
    def snippet_detail(request, pk):
        try:
            snippet = Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            return HttpResponse(status=404)
    
        if request.method == 'GET':
            serializer = SnippetSerializer(snippet)
            return JsonResponse(serializer.data)
    
        elif request.method == 'PUT':
            data = JSONParser().parse(request)
            serializer = SnippetSerializer(snippet, data=data)
            if serializer.is_valid():
                serializer.save()
                return JsonResponse(serializer.data)
            return JsonResponse(serializer.errors, status=400)
    
        elif request.method == 'DELETE':
            snippet.delete()
            return HttpResponse(status=204)
    

    snippets/urls.py

    from django.urls import path
    from snippets import views
    
    urlpatterns = [
        path('snippets/', views.snippet_list),
        path('snippets/<int:pk>/', views.snippet_detail),
    ]
    

    tutorial/urls.py

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
    	path('admin/', admin.site.urls),
        path('', include('snippets.urls')),
    ]
    

    API 테스트 방법: 서버 실행

    python manage.py runserver
    
    🔹 Insomnia 사용
    요청 URL 메서드 설명
    전체 목록 조회 /snippets/ GET 모든 Snippet을 JSON으로 받아옴
    새 Snippet 생성 /snippets/ POST JSON 데이터로 새 Snippet 추가
    특정 Snippet 조회 /snippets/1/ GET ID=1인 Snippet의 상세 정보 조회
    특정 Snippet 수정 .......... /snippets/1/ PUT or PATCH ID=1인 Snippet 수정
    특정 Snippet 삭제 /snippets/1/ DELETE ID=1인 Snippet 삭제
    {
      "title": "Hello World",
      "code": "print('Hello, World!')",
      "language": "python",
      "style": "friendly",
      "linenos": true
    }
    

    httpie로 GET 테스트

    pip install httpie
    
    # 전체 스니펫 목록
    http GET http://127.0.0.1:8000/snippets/
    
    # 특정 스니펫 상세
    http GET http://127.0.0.1:8000/snippets/1/
    
    TOP
    preload preload